#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##-- G04 -- S00 ------------------------------------------------------------##
__all__ = []

from .. import formlib as layout
from .. import pilelib as stack
from ..gamelib import info as gi, game
from ..hint import CautiousDefaultHint
from ..packlib import info as cs, place
from ..utillib.misc import kwdefault
from . import gypsy

GT, SL = gi.GT, gi.SL
Wrap = stack.StackWrapper


class Fifteen(game.Game):
    """
    Finish cards on _foundation within 1 turn.

    _row_
      Pile 15 horz S _foundation_. Init deal [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
      7, 7, 7, 6] open card. Build either in rank by same suit. Play top.

    _foundation_
      Pile 8 N. Build in rank by same suit. E up, W down. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _foundation_: stack.SS_Foundation,
      stack.SS_Foundation (base_rank=KING, dir=-1)
    :cvar Stack _row_: stack.UD_SS_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=673, name="Fifteen", game_type=(GT.BAKERS_DOZEN |
                    GT.OPEN), decks=2, redeals=0, skill_level=SL.MOSTLY_SKILL,
                    version='1.00fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = layout.KlondikeLayout
    _talon_ = stack.InitialDealTalon
    _foundations_ = (stack.SS_Foundation,
                     Wrap(stack.SS_Foundation, base_rank=cs.KING, dir=-1),)
    _row_ = stack.UD_SS_RowStack
    _hint_ = CautiousDefaultHint

    def _create_game(self, **kw):
        kwdefault(kw, rows=15, playcards=15)
        return super(Fifteen, self)._create_game(**kw)

    def _start(self, rows=7, flip=True, **kw):
        for i in range(rows - 1):
            self.s['talon'].dealRow(flip=flip, frames=0)
        self._play_sound('deal')
        self.s['talon'].dealRowAvail()


class Capricieuse(Fifteen):
    """
    Finish cards on _foundation within 3 turn.

    _row_
      Pile 12 horz S _foundation_. Init deal 8 open card. Build either in rank
      by same suit. Play top.

    _talon_
      Pile 1 NW. Redeal all card on _row_.

    _foundation_
      Pile 8 N. Init deal E base ACE, W base KING. Build in rank by same suit.
      E up, W down. Play top.

    seealso::
      http://en.wikipedia.org/wiki/Capricieuse
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.RedealTalon (max_rounds=3)
    :cvar Stack _foundation_: stack.SS_Foundation,
      stack.SS_Foundation (base_rank=KING, dir=-1)
    :cvar Stack _row_: stack.UD_SS_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=292, name="Capricieuse", game_type=(GT.BAKERS_DOZEN |
                    GT.OPEN), decks=2, redeals=2, skill_level=SL.MOSTLY_SKILL,
                    version='0.80fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(stack.RedealTalon, max_rounds=3)

    def _create_game(self, **kw):
        kw.setdefault('rows', 12)
        return super(Capricieuse, self)._create_game(**kw)

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return ACE and KING of suit on bottom by rank, suit, deck for
        _foundation_ deal.
        """
        return place.MoveToBottom(cards, place.OneAceOneKing)

    def _start(self, **kw):
        kw.setdefault('rows', 8)
        return super(Capricieuse, self)._start(**kw)
        self.s['talon'].dealRow(self.s['foundations'])

    def talon_redeal(self, sound=True):
        """
        talon_redeal(self, sound=True):

        Redeal from talon after 1st round after cards returned to refill _row_
        with cards until empty. Returns num cards dealt.
        """
        while self.s['talon'].cards:
            self.s['talon'].dealRowAvail(frames=4)


class Nationale(Capricieuse):
    """
    Finish cards on _foundation within 1 turn.

    _row_
      Pile 12 horz S _foundation_. Init deal 8 open card. Build either in rank
      by same suit wrap. Play top.

    _foundation_
      Pile 8 N. Init deal E base ACE, W base KING. Build in rank by same suit.
      E up, W down. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _foundation_: stack.SS_Foundation,
      stack.SS_Foundation (base_rank=KING, dir=-1)
    :cvar Stack _row_: stack.UD_SS_RowStack (mod=13)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=293, name="Nationale", game_type=(GT.BAKERS_DOZEN |
                    GT.OPEN), decks=2, redeals=0, skill_level=SL.MOSTLY_SKILL,
                    altnames=('Zigzag Course',), version='0.80fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.InitialDealTalon
    _row_ = Wrap(stack.UD_SS_RowStack, mod=13)


class Strata(game.Game):
    """
    Finish cards on _foundation within 3 turn.

    _row_
      Pile 8 horz S _foundation_. Init deal 8 open card. Build either in rank
      by same suit wrap. Play top.

    _talon_
      Pile 1 W. Redeal all card on _row_.

    _foundation_
      Pile 8 N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.StrataLayout
    :cvar Stack _talon_: stack.RedealTalon (max_rounds=3)
    :cvar Stack _foundation_: stack.SS_Foundation,
      stack.SS_Foundation (base_rank=KING, dir=-1)
    :cvar Stack _row_: stack.UD_SS_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=606, name="Strata", game_type=(GT.BAKERS_DOZEN |
                    GT.OPEN), decks=2, redeals=2, skill_level=SL.MOSTLY_SKILL,
                    ranks=cs.SHORT_A7K, altnames=('Persian Patience',),
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = layout.StrataLayout
    _talon_ = Wrap(stack.RedealTalon, max_rounds=3)
    _foundation_ = gypsy.DieRussische_Foundation
    _row_ = Wrap(stack.AC_RowStack, max_move=1, max_accept=1)
    _hint_ = CautiousDefaultHint

    def _create_game(self, **kw):
        kwdefault(kw, rows=8, playcards=12)
        return super(Strata, self)._create_game(self, **kw)

    def _start(self, rows=8, flip=True, **kw):
        for i in range(rows - 1):
            self.s['talon'].dealRow(flip=flip, frames=0)
        self._play_sound('deal')
        self.s['talon'].dealRow()

    def talon_redeal(self, sound=True):
        """
        talon_redeal(self, sound=True):

        Redeal from talon after 1st round after cards returned to refill _row_
        with cards until empty. Returns num cards dealt.
        """
        while self.s['talon'].cards:
            self.s['talon'].dealRowAvail(frames=4)


PROVIDES = [Capricieuse, Nationale, Strata, Fifteen]